package com.digdes.calendar.gwt.client.widget;

import com.digdes.calendar.gwt.client.dto.EventDTOImpl;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;

import java.util.ArrayList;

@SuppressWarnings("deprecation")
public class WeekWidget extends IntervalCalendar implements ClickListener {
    private static WeekWidget instance;

    public static WeekWidget Instance() {
        if (instance == null) {
            instance = new WeekWidget();
        }
        return instance;
    }

    private WeekWidget() {
        super();
        calendarHeader.getFlexCellFormatter().setWidth(0, 0, "60px");
        drawCore();
    }

    @Override
    public void drawCore() {
        for (int i = 0; i < Data.HOURS_TITLE.length; i++) {
            createHourColumn(i);
            for (int k = 1; k < 8; k++) {
                createDaysColumn(i, k);
            }
        }
        drawCalendar();
    }

    @Override
    public void getEvents() {

        int day = DateUtil.getDate().getDay();
        if (DateUtil.getDate().getDay() == 0) day = 6;
        int sDate = DateUtil.getDate().getDate() - (day - 1);
        int sMonth = DateUtil.getMonth();
        int fDate = sDate + 6;
        int fMonth = DateUtil.getMonth();
        int dayNextPrevMonth = DateUtil.getDaysInMonth(DateUtil.getYear(), DateUtil.getMonth() - 1);
        int numOfDays = DateUtil.getDaysInMonth(DateUtil.getYear(), DateUtil.getMonth());
        int dayNextMonth = 1;
        int k = 0;
        if (sDate < 1) {
            for (int iL = day - 1; iL > 0; iL--) {
                k--;
                if ((DateUtil.getDay() + k) < 1) {
                    sDate = dayNextPrevMonth;

                    dayNextPrevMonth--;
                }
            }
            sMonth = DateUtil.getMonth() - 1;
        }
        if (fDate > numOfDays) {
            k = 0;
            dayNextMonth = 1;
            for (int iR = day; iR < 7; iR++) {
                k++;
                if ((DateUtil.getDay() + k) > numOfDays) {
                    fDate = dayNextMonth;
                    dayNextMonth++;
                }
            }
            fMonth = DateUtil.getMonth() + 1;
        }

        String startDate = sDate + "." + (sMonth + 1) + "." + DateUtil.getYear();
        String finishDate = fDate + "." + (fMonth + 1) + "." + DateUtil.getYear();

        calendarService.getEventsBetween(startDate, finishDate, new AsyncCallback<ArrayList<EventDTOImpl>>() {
            public void onFailure(Throwable caught) {
            }

            public void onSuccess(ArrayList<EventDTOImpl> result) {
                eventDTOList.addAll(result);
                setEventInCellDay();
            }
        });
        startDate = null;
        finishDate = null;
    }

    private void setDayMonthInHourGrid(int dayWeek, int dayMonth, int month) {
        for (CellGrid c : gridInCellList)
            if (dayWeek == c.getDayWeek()) {
                c.setDayMonth(dayMonth);
                c.setMonth(month);
            }
    }

    private void prevWeek() {
        //System.out.println((DateUtil.getDay()-9)+"-"+(DateUtil.getDay()-3));
        DateUtil.setDay(DateUtil.getDay() - 7);
    }

    private void nextWeek() {
        //System.out.println((DateUtil.getDay()-9)+"-"+(DateUtil.getDay()-3));
        DateUtil.setDay(DateUtil.getDay() + 7);
    }

    @Override
    public void setDataHeader() {
        int k = 0;
        String[] days = Data.DAYS_SHORT_TITLE;
        int numOfDays = DateUtil.getDaysInMonth(DateUtil.getYear(), DateUtil.getMonth());
        if (DateUtil.getDate().getDay() == 0) {
            calendarHeader.setText(0, 7, days[6] + ", " + (DateUtil.getDay()) +
                    "/" + (DateUtil.getMonth() + 1));
            setDayMonthInHourGrid(6, DateUtil.getDay(), DateUtil.getMonth() + 1);

            int dayNextPrevMonth = DateUtil.getDaysInMonth(DateUtil.getYear(), DateUtil.getMonth() - 1);
            for (int iL = 6; iL > 0; iL--) {
                k--;
                if ((DateUtil.getDay() + k) < 1) {
                    calendarHeader.setText(0, iL, days[iL - 1] + ", " + (dayNextPrevMonth) +
                            "/" + (DateUtil.getMonth()));
                    setDayMonthInHourGrid(iL - 1, dayNextPrevMonth, DateUtil.getMonth());
                    dayNextPrevMonth--;
                } else {
                    calendarHeader.setText(0, iL, days[iL - 1] + ", " + (DateUtil.getDay() + k) +
                            "/" + (DateUtil.getMonth() + 1));
                    setDayMonthInHourGrid(iL - 1, DateUtil.getDay() + k, DateUtil.getMonth() + 1);
                }
            }
        }
        for (int i = 0; i < days.length; i++) {
            if ((DateUtil.getDate().getDay() - 1) == i) {
                calendarHeader.setText(0, i + 1, days[i] + ", " + (DateUtil.getDay()) +
                        "/" + (DateUtil.getMonth() + 1));
                setDayMonthInHourGrid(i, DateUtil.getDay(), DateUtil.getMonth() + 1);

                int dayNextPrevMonth = DateUtil.getDaysInMonth(DateUtil.getYear(), DateUtil.getMonth() - 1);
                for (int iL = i - 1; iL >= 0; iL--) {
                    k--;
                    if ((DateUtil.getDay() + k) < 1) {
                        calendarHeader.setText(0, iL + 1, days[iL] + ", " + dayNextPrevMonth +
                                "/" + (DateUtil.getMonth()));
                        setDayMonthInHourGrid(iL, dayNextPrevMonth, DateUtil.getMonth());
                        dayNextPrevMonth--;
                    } else {
                        calendarHeader.setText(0, iL + 1, days[iL] + ", " + (DateUtil.getDay() + k) +
                                "/" + (DateUtil.getMonth() + 1));
                        setDayMonthInHourGrid(iL, DateUtil.getDay() + k, DateUtil.getMonth() + 1);
                    }
                }
                k = 0;
                int dayNextMonth = 1;
                for (int iR = i + 1; iR < days.length; iR++) {
                    k++;
                    if ((DateUtil.getDay() + k) > numOfDays) {
                        calendarHeader.setText(0, iR + 1, days[iR] + ", " + dayNextMonth +
                                "/" + (DateUtil.getMonth() + 2));
                        setDayMonthInHourGrid(iR, dayNextMonth, DateUtil.getMonth() + 2);
                        dayNextMonth++;
                    } else {
                        calendarHeader.setText(0, iR + 1, days[iR] + ", " + (DateUtil.getDay() + k) +
                                "/" + (DateUtil.getMonth() + 1));
                        setDayMonthInHourGrid(iR, DateUtil.getDay() + k, DateUtil.getMonth() + 1);
                    }
                }
            }

        }
    }

    int moveLeft = 255;
    int moveTop = 0/*78 + calendarHeader.getOffsetHeight()*/;
    int left = 0;

    public void setEventInCellDay() {
        moveTop = gridInCellList.get(0).getAbsoluteTop();
        for (CellGrid c : gridInCellList) {
            left = 0;
            c.getEventDTOList().clear();
            if (c.getDayMonth() == DateUtil.getNowDay()) {
                c.addStyleName("today");
            } else c.removeStyleName("today");
            int countEvent = 0;
            for (EventDTOImpl eventDTO : eventDTOList) {
                if (eventDTO.getDateStart().getDate() == eventDTO.getDateFinish().getDate()
                        && eventDTO.getDateStart().getDate() == c.getDayMonth()
                        && eventDTO.getDateStart().getMonth() + 1 == c.getMonth()
                        && (eventDTO.getDateStart().getYear() + 1900) == DateUtil.getYear()) {
                    if (eventDTO.getDateStart().getHours() == c.getHour()) {
                        countEvent++;
                        c.getEventDTOList().add(eventDTO);
                    }
                }
            }
            for (EventDTOImpl e : c.getEventDTOList()) {
                drawEvent(c, e, countEvent);
            }
            c.setLeft(0);
        }
    }

    private void drawEvent(CellGrid c, EventDTOImpl e, int countEvent) {
        label = createLabel(e);
        String title = e.getNameEvent() + "\n" + e.getDateStart().getHours() + ":" +
                DateUtil.addZeroInMinutes(e.getDateStart().getMinutes()) +
                " - " + e.getDateFinish().getHours() + ":" +
                DateUtil.addZeroInMinutes(e.getDateFinish().getMinutes());
        float minutes = (float) ((e.getDateFinish().getMinutes() - e.getDateStart().getMinutes()) * 0.8);
        int minutesStart = (int) (e.getDateStart().getMinutes() * 0.8);
        label.setHeight(String.valueOf((e.getDateFinish().getHours() -
                e.getDateStart().getHours()) * 50 + minutes - 3));
        // System.out.println((e.getDateFinish().getHours() - e.getDateStart().getHours()) * 50 + minutes - 3);
        label.setStyleName("EventLabelDay");
        label.setWidth(String.valueOf((Util.WIDTH_WEEK_CELL / countEvent) - 6));
        label.setText(title);
        label.setTitle(title);
        aPanel.add(label, c.getAbsoluteLeft() - moveLeft + c.getLeft(),
                minutesStart + c.getAbsoluteTop() - moveTop);
        left += (Util.WIDTH_WEEK_CELL / countEvent);
        c.setLeft(left);
        eventLabels.add(label);
        title = null;
    }

    /*public void onClick(Widget sender) {
        label = (EventLabel) sender;
        eventDBox.draw(label.getEventDTO());
        eventDBox.deleteBtn.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                deleteEvent(label);
            }
        });
        eventDBox.center();
    }
*/
    private void deleteEvent(final EventLabel label) {
        eventDBox.deleteEvent(label, eventLabels);
        //drawCalendar();
        for (CellGrid c : gridInCellList) {
            c.getEventDTOList().remove(label.getEventDTO());
        }
    }

    @Override
    protected Widget getNavBar() {
        return new NavBar();
    }

    protected class NavBar extends Composite implements ClickListener {

        public DockPanel bar = new DockPanel();
        public Button prevDay = new Button("&lt;", this);
        // public Button prevYear = new Button("«", this);
        //public Button nextYear = new Button("»", this);
        public Button nextDay = new Button("&gt;", this);
        public HTML titleYear = new HTML();

        public NavBar() {
            setWidget(bar);
            bar.setStyleName("navbar");
            titleYear.setStyleName("header");

            HorizontalPanel prevButtons = new HorizontalPanel();
            prevButtons.add(prevDay);

            HorizontalPanel nextButtons = new HorizontalPanel();
            nextButtons.add(nextDay);

            Grid gridTitleYear = new Grid(1, 1);

            gridTitleYear.setWidget(0, 0, titleYear);

            bar.add(prevButtons, DockPanel.WEST);
            bar.setCellHorizontalAlignment(prevButtons, DockPanel.ALIGN_LEFT);
            bar.add(nextButtons, DockPanel.EAST);
            bar.setCellHorizontalAlignment(nextButtons, DockPanel.ALIGN_RIGHT);
            bar.add(gridTitleYear, DockPanel.CENTER);
            bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
            bar.setCellHorizontalAlignment(gridTitleYear,
                    HasAlignment.ALIGN_CENTER);
            bar.setCellVerticalAlignment(gridTitleYear,
                    HasAlignment.ALIGN_MIDDLE);
            bar.setCellWidth(gridTitleYear, "100%");
        }

        public void onClick(Widget sender) {
            if (sender == prevDay) {
                prevWeek();
            } else if (sender == nextDay) {
                nextWeek();
            }

            drawCalendar();
        }
    }
}
